/*
 * Copyright (c) 2010, Nikolaus Moll
 * All rights reserved.
 */
package net.miblounge.gradecalculator.core.descriptors.courses;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import net.miblounge.gradecalculator.core.descriptors.modulelistitems.Module;
import net.miblounge.gradecalculator.core.enums.CourseTypeList;
import net.miblounge.gradecalculator.core.enums.ExaminationTypeList;
import net.miblounge.gradecalculator.core.interfaces.IModuleIdentificator;
import net.miblounge.gradecalculator.core.serialization.CourseTypeListAdapter;
import net.miblounge.gradecalculator.core.serialization.ExaminationTypeListAdapter;

@XmlRootElement(namespace = "http://gradecalculator.net/")
@XmlType( 
 propOrder = { "name", "type", "gradedPerformance", "ungradedPerformance", "ECTS", "hoursPerWeek", "semester", "examNumber", "courseNumber", "sortOrder" } 
) 
public class Course implements Comparable<Course>, IModuleIdentificator {
	private String name;
	private float ects;
	private CourseTypeList type;
	private ExaminationTypeList gradedPerformance;
	private ExaminationTypeList ungradedPerformance;
	private int examNumber;
	private int courseNumber;

	private int semester;
	private int hoursPerWeek;
	
	private IModuleIdentificator parent;
	
	private int sortOrder;

	public Course() {
		this("");
	}

	public Course(final String name) {
		this.name = name;
		this.type = new CourseTypeList();
		this.gradedPerformance = new ExaminationTypeList();
		this.ungradedPerformance = new ExaminationTypeList();
	}
	
	public void setParent(final IModuleIdentificator parent)
	{
		this.parent = parent;
	}
	
	@XmlTransient
	public IModuleIdentificator getParent()
	{
		return parent;
	}
	
	@XmlElement(name = "name") 
	public String getName() {
		return name;
	}
	public void setName(final String name) {
		this.name = name;
	}
	
	@XmlElement(name = "ects") 
	public float getECTS() {
		return ects;
	}
	public void setECTS(final float ects) {
		this.ects = ects;
		invalidate();
	}
	
	@XmlElement(name = "type") 
	@XmlJavaTypeAdapter(CourseTypeListAdapter.class)
	public CourseTypeList getType() {
		return type;
	}
	public void setType(final CourseTypeList type) {
		this.type = type;
	}
	
	@XmlElement(name = "gradedperformance") 
	@XmlJavaTypeAdapter(ExaminationTypeListAdapter.class)
	public ExaminationTypeList getGradedPerformance() {
		return gradedPerformance;
	}
	public void setGradedPerformance(final ExaminationTypeList gradedPerformances) {
		this.gradedPerformance = gradedPerformances;
	}
	
	@XmlElement(name = "ungradedperformance") 
	@XmlJavaTypeAdapter(ExaminationTypeListAdapter.class)
	public ExaminationTypeList getUngradedPerformance() {
		return ungradedPerformance;
	}
	public void setUngradedPerformance(final ExaminationTypeList ungradedPerformances) {
		this.ungradedPerformance = ungradedPerformances;
	}
	
	@XmlElement(name = "semester") 
	public int getSemester() {
		return semester;
	}
	public void setSemester(final int semester) {
		this.semester = semester;
	}

	@XmlElement(name = "hoursperweek") 
	public int getHoursPerWeek() {
		return hoursPerWeek;
	}
	public void setHoursPerWeek(final int hoursPerWeek) {
		this.hoursPerWeek = hoursPerWeek;
		invalidate();
	}
	
	@XmlElement(name = "sortorder") 
	public int getSortOrder() {
		return sortOrder;
	}
	public void setSortOrder(final int sortOrder) {
		this.sortOrder = sortOrder;
	}
	
	@XmlElement(name = "examnumber") 
	public int getExamNumber() {
		return examNumber;
	}
	public void setExamNumber(final int examNumber) {
		invalidate();
		this.examNumber = examNumber;
	}

	@XmlElement(name = "coursenumber") 
	public int getCourseNumber() {
		return courseNumber;
	}
	public void setCourseNumber(final int courseNumber) {
		invalidate();
		this.courseNumber = courseNumber;
	}

	@Override
	public int compareTo(final Course course) {
		return this.sortOrder - course.sortOrder;
	}

	@Override
	public String toString()
	{
		return getName();
	}

	@Override
	public String getIdentifier() {
		if (parent != null) {
			return parent.getIdentifier() + "." + name;
		}
		return name;
	}
	
	protected void invalidate()
	{
		if (parent != null) {
			((Module)parent).invalidate();
		}
	}
}
